import React from 'react';
import api, { client } from './request';

const GlobalConext = React.createContext();

let userInStorage = JSON.parse(window.localStorage.getItem('user'));
client.authentications.oauth2.accessToken = userInStorage?.token;

/**
 * @typedef {object} User
 * @property {number?} id
 * @property {string?} nickname
 * @property {string?} email
 * @property {string?} phoneNumber
 * @property {string?} role
 * @property {string?} token
 */

let defaultGlobalContext = {
    /** @type {User} */
    user: userInStorage || {
        id: null,
        nickname: null,
        email: null,
        phoneNumber: null,
        role: null,
        token: null
    },
    dispatch: () => {},

};

/**
* 登录
* @param {string} email
* @param {string} password
*/
function login(state, email, password, rememberMe, onSuccess, onFail) {
    console.log('login', email, password, rememberMe);
    let passwordHash = password; // TODO md5 password
    api.login({ email, password: passwordHash }, (err, data, res) => {
        if (data.code !== 0) {
            onFail?.(err, res.body);
            return;
        }
        onSuccess?.(data);
        let userObj = { ...data.data.user, token: data.data.token };
        state.dispatch({
            type: 'set-user',
            payload: {
                user: userObj,
                rememberMe
            }
        });
    });
}

function register(state, email, password, nickname, phoneNumber, rememberMe, onSuccess, onFail) {
    console.log('register', email, password, nickname, phoneNumber, rememberMe);
    let passwordHash = password; // TODO md5 password
    api.register({ nickname, email, password: passwordHash, phoneNumber }, (err, data, _) => {
        if (data.code !== 0) {
            onFail?.(data);
            return;
        }
        onSuccess?.(data);
    });
}

function setUser(state, payload) {
    // 持久化储存
    if (payload.rememberMe)
        window.localStorage.setItem('user', JSON.stringify(payload.user));
    // 设置 api
    client.authentications.oauth2.accessToken = payload.user.token;
    return { ...state, user: payload.user };
}

function logout(state) {
    window.localStorage.removeItem('user');
    state.dispatch({
        type: 'set-user',
        payload: {
            user:{
                id: null,
                nickname: null,
                email: null,
                phoneNum: null,
                role: null,
                token: null
            },
            rememberMe: true
        }
    });
}

function globalReducer(state, action) {
    let payload = action.payload;
    console.log('globalReducer', action, state);

    switch (action.type) {
        case 'login':
            login(state, payload.email, payload.password, payload.rememberMe, payload.onSuccess, payload.onFail);
            return state;
        case 'register':
            register(state, payload.email, payload.password, payload.nickname, payload.phone, payload.rememberMe, payload.onSuccess, payload.onFail);
            return state;
        case 'logout':
            logout(state);
            return state;
        case 'set-user':
            return setUser(state, payload);
        case 'set-dispatch':
            return { ...state, dispatch: payload };
        default:
            return state;
    }
}

/**
 * @typedef {object} GlobalContextObject
 * @property {User} user
 * @property {React.Dispatch} dispatch
 */

/**
 * 
 * @returns {[GlobalContextObject, React.Dispatch<GlobalContextObject>]}
 
 */
function useGlobalConext() {
    return React.useContext(GlobalConext);
}

export { GlobalConext, defaultGlobalContext, globalReducer };
export default useGlobalConext;